package com.ll.studentservice.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ll.commonUtils.JwtUtils;
import com.ll.commonUtils.MD5;
import com.ll.commonUtils.R;
import com.ll.studentservice.entity.EduStudent;
import com.ll.studentservice.entity.vo.*;
import com.ll.studentservice.service.EduStudentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 学生 前端控制器
 * </p>
 *
 * @author ll
 * @since 2020-11-26
 */
@Api(description = "学生登录注册信息增删改查API") //swagger界面提示
@RestController
@RequestMapping("/studentservice/student")
//@CrossOrigin
public class EduStudentController {

    @Autowired
    private EduStudentService eduStudentService;

    //根据班级id,查询该班级所有学生
    @GetMapping("findAllByClassId/{classId}")
    @ApiOperation(value = "查询某个班级的所有学生") //swagger界面提示
    public R findAllByClassId(@PathVariable String classId){
        QueryWrapper<EduStudent> wrapper = new QueryWrapper<>();
        wrapper.eq("class_id", classId);
        List<EduStudent> eduStudents = eduStudentService.list(wrapper);

        //去除密码等信息
        List<EduStudentInfo> eduStudentInfos = new ArrayList<>();
        for (EduStudent eduStudent : eduStudents) {
            EduStudentInfo eduStudentInfo = new EduStudentInfo();
            BeanUtils.copyProperties(eduStudent, eduStudentInfo);
            eduStudentInfos.add(eduStudentInfo);
        }

        int total = eduStudentInfos.size();

        return R.ok().data("total", total).data("items", eduStudentInfos);
    }

    //查询单个学生
    @GetMapping("findOne/{studentId}")
    @ApiOperation(value = "查询单个学生(根据学生Id)") //swagger界面提示
    public R findOneStudent(@PathVariable String studentId){
        EduStudent eduStudent = eduStudentService.getById(studentId);
        EduStudentInfo eduStudentInfo = new EduStudentInfo();
        BeanUtils.copyProperties(eduStudent, eduStudentInfo);

        return R.ok().data("studentInfo", eduStudentInfo);
    }

    //1.查询所有学生
    @GetMapping("findAll")
    @ApiOperation(value = "查询所有学生,返回学生列表") //swagger界面提示
    public R findAllStudent() {
        //调用service层的方法实现查询所有操作
        List<EduStudent> studentList = eduStudentService.list(null);

        //过滤掉密码之类的敏感信息
        List<EduStudentInfo> newStudents = new ArrayList<>();
        for (EduStudent student : studentList) {
            EduStudentInfo eduStudentInfo = new EduStudentInfo();
            BeanUtils.copyProperties(student,eduStudentInfo);
            newStudents.add(eduStudentInfo);
        }

        return R.ok().data("items", newStudents);
    }

    //2.逻辑删除学生的方法
    @DeleteMapping("{id}")
    @ApiOperation(value = "逻辑删除学生") //swagger界面提示
    public R removeTeacher(@ApiParam(name = "id", value = "学生ID", required = true) @PathVariable("id") String id) {

        //因为逻辑不管是否删除成功都会返回true,所以先通过查询,判断是否有这个学生Id,
        //对象不为空证明有这个id,在进行逻辑删除, 否则返回错误
        EduStudent eduStudent = eduStudentService.getById(id);
        if (StringUtils.isEmpty(eduStudent)){
            return R.error().message("没有改学生信息,删除失败");
        }

        //逻辑删除
        eduStudentService.removeById(id);

        return R.ok().message("删除成功");
    }

    /**
     * 3.分页查询学生的方法
     * 要在EduConfig配置文件中引入分页插件
     * current 当前页
     * limit 每页记录数
     */
    @ApiOperation("查询所有学生(只具有分页功能,不带查询条件,GET方式)")
    @GetMapping("pageStudent/{current}/{limit}")
    public R pageListStudent(@ApiParam(name = "current", value = "当前页码", required = true)
                             @PathVariable("current") long current,
                             @ApiParam(name = "limit", value = "每页记录数", required = true)
                             @PathVariable("limit") long limit) {

        //创建page对象
        Page<EduStudent> pageStudent = new Page<>(current, limit);

        //调用方法实现分页
        //调用方法的时候,底层封装,把分页所有数据封装到pageTeacher对象里面
        eduStudentService.page(pageStudent, null);

        long total = pageStudent.getTotal(); //总记录数
        List<EduStudent> studentList = pageStudent.getRecords(); //数据list集合

        //过滤掉密码之类的敏感信息
        List<EduStudentInfo> studentInfoList = new ArrayList<>();
        for (EduStudent student : studentList) {
            EduStudentInfo eduStudentInfo = new EduStudentInfo();
            BeanUtils.copyProperties(student,eduStudentInfo);
            studentInfoList.add(eduStudentInfo);
        }

        return R.ok().data("total", total).data("studentInfoList", studentInfoList);
    }

    /**
     * 4. 条件查询,带分页 POST方式
     * 要在EduConfig配置文件中引入分页插件
     * Condition条件
     */
    @ApiOperation(value = "查询所有学生(带分页功能,带条件,POST方式)")
    @PostMapping("pageStudentCondition/{current}/{limit}")
    public R pageStudentConditionByPOST(@ApiParam(name = "current", value = "当前页码", required = true)
                                        @PathVariable("current") long current,
                                        @ApiParam(name = "limit", value = "每页记录数", required = true)
                                        @PathVariable("limit") long limit,
                                        @ApiParam(name = "studentQuery", value = "查询条件", required = false)
                                        @RequestBody(required = false) StudentQuery studentQuery) {
        //创建page对象
        Page<EduStudent> pageStudent = new Page<>(current, limit);

        //构建条件
        QueryWrapper<EduStudent> wrapper = new QueryWrapper<>();

        //多条件组合查询
        //mybatis学过 动态sql
        //判断条件值是否为空,如果不为空拼接条件
        String name = studentQuery.getName();
        String begin = studentQuery.getBegin();
        String end = studentQuery.getEnd();

        //判断条件值是否为空,如果不为空拼接条件
        if (!StringUtils.isEmpty(name)) {
            //构建条件
            wrapper.like("name", name);
        }
        if (!StringUtils.isEmpty(begin)) {
            //构建条件
            wrapper.ge("gmt_create", begin);

        }
        if (!StringUtils.isEmpty(end)) {
            //构建条件
            wrapper.le("gmt_modified", end);
        }

        //排序
        wrapper.orderByDesc("gmt_create");

        //调用方法实现条件查询分页
        //调用方法的时候,底层封装,把分页所有数据封装到pageTeacher对象里面
        eduStudentService.page(pageStudent, wrapper);

        long total = pageStudent.getTotal(); //总记录数
        List<EduStudent> studentList = pageStudent.getRecords(); //数据list集合

        //过滤掉密码之类的敏感信息
        List<EduStudentInfo> studentInfoList = new ArrayList<>();
        for (EduStudent student : studentList) {
            EduStudentInfo eduStudentInfo = new EduStudentInfo();
            BeanUtils.copyProperties(student,eduStudentInfo);
            studentInfoList.add(eduStudentInfo);
        }

        return R.ok().data("total", total).data("studentInfoList", studentInfoList);
    }

    /**
     * 5 条件查询,带分页 GET方式
     * Condition条件
     */
    @ApiOperation(value = "查询所有学生(带分页功能,带条件,GET方式)")
    @GetMapping("pageStudentCondition/{current}/{limit}")
    public R pageStudentConditionByGET(@ApiParam(name = "current", value = "当前页码", required = true)
                                       @PathVariable("current") long current,
                                       @ApiParam(name = "limit", value = "每页记录数", required = true)
                                       @PathVariable("limit") long limit,
                                       @ApiParam(name = "studentQuery", value = "查询条件", required = false)
                                       StudentQuery studentQuery) {
        //创建page对象
        Page<EduStudent> pageStudent = new Page<>(current, limit);

        //构建条件
        QueryWrapper<EduStudent> wrapper = new QueryWrapper<>();

        //多条件组合查询
        //mybatis学过 动态sql
        //判断条件值是否为空,如果不为空拼接条件
        String name = studentQuery.getName();
        String begin = studentQuery.getBegin();
        String end = studentQuery.getEnd();

        //判断条件值是否为空,如果不为空拼接条件
        if (!StringUtils.isEmpty(name)) {
            //构建条件
            wrapper.like("name", name);
        }
        if (!StringUtils.isEmpty(begin)) {
            //构建条件
            wrapper.ge("gmt_create", begin);
        }
        if (!StringUtils.isEmpty(end)) {
            //构建条件
            wrapper.le("gmt_modified", end);
        }

        //调用方法实现条件查询分页
        //调用方法的时候,底层封装,把分页所有数据封装到pageTeacher对象里面
        eduStudentService.page(pageStudent, wrapper);

        long total = pageStudent.getTotal(); //总记录数
        List<EduStudent> studentList = pageStudent.getRecords(); //数据list集合

        //过滤掉密码之类的敏感信息
        List<EduStudentInfo> studentInfoList = new ArrayList<>();
        for (EduStudent student : studentList) {
            EduStudentInfo eduStudentInfo = new EduStudentInfo();
            BeanUtils.copyProperties(student,eduStudentInfo);
            studentInfoList.add(eduStudentInfo);
        }

        return R.ok().data("total", total).data("studentInfoList", studentInfoList);
    }

    /**
     * 6 添加学生方法
     */
    @ApiOperation("手动添加学生")
    @PostMapping("addStudnet")
    public R addStudnet(@RequestBody AddStudent addStudent) {
        //加密密码
        addStudent.setPassword(MD5.encrypt(addStudent.getPassword()));

        EduStudent eduStudent = new EduStudent();
        BeanUtils.copyProperties(addStudent, eduStudent);

        boolean save = eduStudentService.save(eduStudent);

        //三元运算符
        return save ? R.ok() : R.error();
    }

    /**
     * 6 根据ID修改学生POST方式
     */
    @ApiOperation(value = "修改学生(根据ID,POST方式)") //swagger界面提示
    @PostMapping("updateStudent")
    public R updateStudentByIdPOST(
            @ApiParam(name = "updateStudent", value = "学生对象", required = true)
            @RequestBody UpdateStudent updateStudent) {

        //密码加密
        if (!StringUtils.isEmpty(updateStudent.getPassword())){
            updateStudent.setPassword(MD5.encrypt(updateStudent.getPassword()));
        }

        EduStudent eduStudent = new EduStudent();
        BeanUtils.copyProperties(updateStudent, eduStudent);

        boolean flag = eduStudentService.updateById(eduStudent);
        return flag ? R.ok() : R.error();
    }

    //学生注册
    @ApiOperation(value = "学生注册") //swagger界面提示
    @PostMapping("register")
    public R registerUser(@RequestBody RegisterVo registerVo){
        eduStudentService.register(registerVo);
        return R.ok();
    }

    //学生登录
    @ApiOperation(value = "学生登录,传递手机号和密码,暂时不需要验证码") //swagger界面提示
    @PostMapping("login")
    public R loginUser(@RequestBody LoginVo loginVo){
        //loginVo对象里面封装手机号和密码
        //登录成功,返回token值,使用jwt生成
        String token = eduStudentService.login(loginVo);

        return  R.ok().data("token", token);
    }

    //根据token获取用户信息
    @ApiOperation(value = "根据token获取用户信息(swagger里面不能测试,要在Postman里测试,参数:header中的key为token,value为登录后返回的token字符串)") //swagger界面提示
    @GetMapping("getStudentInfo")
    public R getStudentInfo(HttpServletRequest request){
        System.out.println("EduStudentController ==> getStudentInfo(根据token获取用户信息)");

        //调用jwt工具类的方法,根据request对象获取头信息,返回用户id
        String studentId = JwtUtils.getMemberIdByJwtToken(request);

        //查询数据库,根据用户id查询用户数据
        EduStudent student = eduStudentService.getById(studentId);

        if (StringUtils.isEmpty(student)){
            return R.error().message("用户未登陆");
        }

        //因为student对象里有密码之类的的敏感信息,创建一个新的实体类(EduStudentInfo)封装
        EduStudentInfo eduStudentInfo = new EduStudentInfo();
        BeanUtils.copyProperties(student, eduStudentInfo);

        return R.ok().data("studentInfo", eduStudentInfo);
    }

}

